// Mbuf.h: interface for the CMSockbuf class.
//
//////////////////////////////////////////////////////////////////////

#ifndef __MBUF_H
#define __MBUF_H

#include "MCommon.h"

class CStr
{
public:
	int length;
	char *m_pData;

public:
	CStr();
	CStr(char* ptr,int n);
	virtual ~CStr();
};

class CBuf  
{
private:
public:
	static const int DEFAULT_BUFFER_SIZE;
	BOOL m_bIsSet;
	int m_nSize;
	char *m_pRewindTailPtr;
	char *m_pRewindHeadPtr;
	char *m_pData;
	char *m_pHead;
	char *m_pTail;
	inline CBuf& operator <<(short value);
	inline CBuf& operator <<(int value);
	inline CBuf& operator <<(long value);
	inline CBuf& operator <<(DWORD value);
	inline CBuf& operator <<(BYTE value);
	inline CBuf& operator <<(WORD value);
	inline CBuf& operator <<(CStr& value);
	inline CBuf& operator <<(char* value);


	inline CBuf& operator >>(short& value);
	inline CBuf& operator >>(int& value);
	inline CBuf& operator >>(WORD& value);
	inline CBuf& operator >>(long& value);
	inline CBuf& operator >>(DWORD& value);
	inline CBuf& operator >>(BYTE& value);
	inline CBuf& operator >>(CStr& value);
	inline CBuf& operator >>(char* value);

	void Clear();

	void Set(char* ptr, int n);
	int Get(char* ptr, int n);
	int GetLength() { return m_pTail-m_pHead; };
	void Markwind()
	{ 
		m_pRewindTailPtr = m_pTail;
		m_pRewindHeadPtr = m_pHead;
	}
	void Rewind()
	{ 
		m_pTail = m_pRewindTailPtr;
		m_pHead = m_pRewindHeadPtr;
	};

public:
	CBuf();
	CBuf(int size);
	CBuf(char *pdata, int n);

	virtual ~CBuf();

};

inline CBuf& CBuf::operator <<(short value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead + 2 <= m_nSize);
#endif

	/*
	int i;
	MYSHORT i_temp;
	i_temp.i = value;

	for( i = 0; i < 2; i ++) *(m_pTail++)=i_temp.b[i];
	*/

	*((short*)m_pTail)=(short)value,m_pTail+=sizeof(short);

	return *this;
}

inline CBuf& CBuf::operator <<(int value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead + 4 <= m_nSize);
#endif

	//int i;
	//MYINT i_temp;
	//i_temp.i = value;

	//for( i = 0; i < 4; i ++) *(m_pTail++)=i_temp.b[i];

	*((int*)m_pTail)=(int)value,m_pTail+=sizeof(int);

	return *this;
}

inline CBuf& CBuf::operator <<(WORD value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead + 2 <= m_nSize);
#endif

	//int i;
	//MYSHORT i_temp;
	//i_temp.i = value;

	//for( i = 0; i < 2; i ++) *(m_pTail++)=i_temp.b[i];

	*((WORD*)m_pTail)=(WORD)value,m_pTail+=sizeof(WORD);

	return *this;
}

inline CBuf& CBuf::operator <<(long value)
{
#ifdef _DEBUG
	if ( m_nSize!=-1 ) 
		ASSERT(m_pTail - m_pHead + 4 <= m_nSize);
#endif
	
	//int i;
	//MYDWORD i_temp;
	//i_temp.w = value;

	//for( i = 0; i < 4; i ++) *(m_pTail++)=i_temp.b[i];

	*((long*)m_pTail)=(long)value,m_pTail+=sizeof(long);

	return *this;
}

inline CBuf& CBuf::operator <<(DWORD value)
{
#ifdef _DEBUG
	if ( m_nSize!=-1 ) 
		ASSERT(m_pTail - m_pHead + 4 <= m_nSize);
#endif
	
	//int i;
	//MYDWORD i_temp;
	//i_temp.w = value;

	//for( i = 0; i < 4; i ++) *(m_pTail++)=i_temp.b[i];

	*((DWORD*)m_pTail)=(DWORD)value,m_pTail+=sizeof(DWORD);

	return *this;
}

inline CBuf& CBuf::operator <<(BYTE value)
{
#ifdef _DEBUG
	if (m_nSize != -1) 
		ASSERT(m_pTail - m_pHead +1 <= m_nSize);
#endif

	*(m_pTail++)=value;

	return *this;
}

inline CBuf& CBuf::operator <<(CStr& value)
{
#ifdef _DEBUG
	if (m_nSize != -1)
		ASSERT(m_pTail - m_pHead + value.length <= m_nSize);
#endif

	memcpy(m_pTail,value.m_pData,value.length);
	m_pTail+=value.length;

	return *this;
}

inline CBuf& CBuf::operator <<(char* value)
{
	if ( m_nSize != -1 )
		ASSERT(m_pTail - m_pHead + (int)(strlen(value))+1 <= m_nSize);
 
	CStr tmp(value,strlen(value)+1);
	*this << tmp;

	return *this;
}

inline CBuf& CBuf::operator >>(short& value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead -2 >= 0);
#endif

	//int i;
	//MYSHORT i_temp;

	//for( i = 0; i < 2; i ++) i_temp.b[i] = *(m_pHead++);
	//value = i_temp.i;

	*((short*)(&value))=*((short*)m_pHead),m_pHead+=sizeof(short);

	return *this;
}

inline CBuf& CBuf::operator >>(int& value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead - 4 >= 0);
#endif

	//int i;
	//MYINT i_temp;

	//for( i = 0; i < 4; i ++) i_temp.b[i] = *(m_pHead++);
	//value = i_temp.i;

	*((int*)(&value))=*((int*)m_pHead),m_pHead+=sizeof(int);

	return *this;
}

inline CBuf& CBuf::operator >>(WORD& value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead -2 >= 0);
#endif

	//int i;
	//MYSHORT i_temp;

	//for( i = 0; i < 2; i ++) i_temp.b[i] = *(m_pHead++);
	//value = i_temp.i;

	*((WORD*)(&value))=*((WORD*)m_pHead),m_pHead+=sizeof(WORD);

	return *this;
}

inline CBuf& CBuf::operator >>(long& value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead - 4 >= 0);
#endif

	//int i;
	//MYDWORD i_temp;

	//for( i = 0; i < 4; i ++) i_temp.b[i] = *(m_pHead++);
	//value = i_temp.w;

	*((long*)(&value))=*((long*)m_pHead),m_pHead+=sizeof(long);

	return *this;
}

inline CBuf& CBuf::operator >>(DWORD& value)
{
#ifdef _DEBUG
	if (m_nSize!=-1) 
		ASSERT(m_pTail - m_pHead - 4 >= 0);
#endif

	//int i;
	//MYDWORD i_temp;

	//for( i = 0; i < 4; i ++) i_temp.b[i] = *(m_pHead++);
	//value = i_temp.w;

	*((DWORD*)(&value))=*((DWORD*)m_pHead),m_pHead+=sizeof(DWORD);

	return *this;
}

inline CBuf& CBuf::operator >>(BYTE& value)
{
#ifdef _DEBUG
	if (m_nSize != -1)
		ASSERT(m_pTail - m_pHead -1 >= 0);
#endif

	value = *(m_pHead++);

	return *this;
}
 
inline CBuf& CBuf::operator >>(CStr& value)
{	
//	if ( m_nSize != -1 )
//	{
//		if ( m_nSize < value.length )
//			ASSERT(m_pTail - m_pHead - m_nSize < 0);
//		else
//			ASSERT(m_pTail - m_pHead - value.length < 0);
//	}

	memcpy(value.m_pData,m_pHead,value.length);
	*(value.m_pData+value.length)='\0';
	m_pHead+=value.length;

	return *this;
}

inline CBuf& CBuf::operator >>(char* value)
{
	strcpy(value,m_pHead);
	m_pHead +=strlen(m_pHead)+1;

	return *this;
}

#endif
